package ru.braim.weather_app.controllers;

import jakarta.annotation.Nullable;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import ru.braim.weather_app.dto.account.AccountRequestDTO;
import ru.braim.weather_app.dto.account.AccountResponseDTO;
import ru.braim.weather_app.responses.account.AccountResponse;
import ru.braim.weather_app.responses.account.AccountsResponse;
import ru.braim.weather_app.services.AccountService;
import ru.braim.weather_app.services.CookieService;

import java.util.List;

@RestController
public class AccountController {

    private final AccountService accountService;
    private final CookieService cookieService;

    public AccountController(AccountService accountService, CookieService cookieService) {
        this.accountService = accountService;
        this.cookieService = cookieService;
    }

    @PostMapping("/registration")
    public ResponseEntity<AccountResponseDTO> registration(@RequestBody AccountRequestDTO accountDTO,
                                                           @CookieValue("id") @Nullable String cookie,
                                                           HttpServletResponse response,
                                                           HttpServletRequest request) {

        String cookieId = request.getSession().getId();

        if (cookie != null && !cookie.isEmpty() && accountService.checkCookieInAccount(cookie)) {
            return new ResponseEntity<>(null, HttpStatus.FORBIDDEN);
        }

        AccountResponse accountResponse = accountService.createAccount(accountDTO, cookieId);

        if (accountResponse.getHttpStatus().equals(HttpStatus.BAD_REQUEST)) {
            return new ResponseEntity<>(null, accountResponse.getHttpStatus());
        }

        if (accountResponse.getHttpStatus().equals(HttpStatus.CONFLICT)) {
            return new ResponseEntity<>(null, accountResponse.getHttpStatus());
        }


        if (accountResponse.getHttpStatus().equals(HttpStatus.CREATED)) {
            response.addCookie(cookieService.createCookie(cookieId));
        }

        return new ResponseEntity<>(accountResponse.getAccountResponseDTO(), accountResponse.getHttpStatus());
    }

    @PostMapping("/login")
    public ResponseEntity<AccountResponseDTO> login(@RequestBody AccountRequestDTO accountRequestDTO,
                                                    @CookieValue("id") @Nullable String cookie,
                                                    HttpServletResponse response,
                                                    HttpServletRequest request) {

        String cookieId = request.getSession().getId();

        AccountResponse accountResponse = accountService.authInAccount(accountRequestDTO);

        if (cookie != null && !cookie.isEmpty() && accountService.checkCookieInAccount(cookie)) {
            return new ResponseEntity<>(null, HttpStatus.OK);
        }

        if (accountResponse.getHttpStatus().equals(HttpStatus.OK)) {
            response.addCookie(cookieService.createCookie(cookieId));
            if (!accountService.updateCookieInAccount(accountResponse.getAccountResponseDTO(), cookieId)) {
                return new ResponseEntity<>(null, HttpStatus.UNAUTHORIZED);
            }
        }

        return new ResponseEntity<>(accountResponse.getAccountResponseDTO(), accountResponse.getHttpStatus());
    }
    @GetMapping("/accounts/{accountId}")
    public ResponseEntity<AccountResponseDTO> getAccountById(@PathVariable String accountId,
                                                             @CookieValue("id") @Nullable String cookie) {

        try {

            if (!cookieService.checkAuthorizeCookie(cookie)) {
                return new ResponseEntity<>(null, HttpStatus.UNAUTHORIZED);

            }

            AccountResponse accountResponse = accountService.getAccountById(Integer.parseInt(accountId));
            return new ResponseEntity<>(accountResponse.getAccountResponseDTO(), accountResponse.getHttpStatus());
        }
        catch (NumberFormatException e) {
            return new ResponseEntity<>(null, HttpStatus.BAD_REQUEST);
        }
    }

    @GetMapping("/accounts/search")
    public ResponseEntity<List<AccountResponseDTO>> searchAccounts(@CookieValue("id") @Nullable String cookie,
                                                                   @RequestParam(defaultValue = "") String firstName,
                                                                   @RequestParam(defaultValue = "") String lastName,
                                                                   @RequestParam(defaultValue = "") String email,
                                                                   @RequestParam(defaultValue = "0") String form,
                                                                   @RequestParam(defaultValue = "10") String size) {

        try {

            if (!cookieService.checkAuthorizeCookie(cookie)) {
                return new ResponseEntity<>(null, HttpStatus.UNAUTHORIZED);
            }

            int formInt = Integer.parseInt(form);
            int sizeInt = Integer.parseInt(size);


            AccountsResponse accountsResponse =
                    accountService.getAccountsBySearch(firstName,lastName,email, formInt,sizeInt);

            return new ResponseEntity<>(accountsResponse.getAccountsResponseDTO(), accountsResponse.getHttpStatus());
        } catch (NumberFormatException e) {
            return new ResponseEntity<>(null, HttpStatus.BAD_REQUEST);
        }

    }

    @PutMapping("/accounts/{accountId}")
    public ResponseEntity<AccountResponseDTO> updateAccountById(@RequestBody AccountRequestDTO accountRequestDTO,
                                                                @PathVariable String accountId,
                                                                @CookieValue("id") @Nullable String cookie) {
        try {

            if (!cookieService.checkAuthorizeCookie(cookie)) {
                return new ResponseEntity<>(null, HttpStatus.UNAUTHORIZED);
            }

            AccountResponse accountResponse = accountService
                    .updateAccount(Integer.parseInt(accountId), accountRequestDTO, cookie);

            return new ResponseEntity<>(accountResponse.getAccountResponseDTO(), accountResponse.getHttpStatus());
        }
        catch (NumberFormatException e) {
            return new ResponseEntity<>(null, HttpStatus.BAD_REQUEST);
        }
    }

    @DeleteMapping("/accounts/{accountId}")
    public ResponseEntity<AccountResponseDTO> deleteAccountById(@RequestBody @Nullable AccountRequestDTO accountRequestDTO,
                                                                @PathVariable String accountId,
                                                                @CookieValue("id") @Nullable String cookie,
                                                                HttpServletResponse response) {
        try {

            if (!cookieService.checkAuthorizeCookie(cookie)) {
                return new ResponseEntity<>(null, HttpStatus.UNAUTHORIZED);
            }

            AccountResponse accountResponse = accountService
                    .deleteAccount(Integer.parseInt(accountId), cookie);

            if (accountResponse.getHttpStatus().equals(HttpStatus.OK)) {
                response.addCookie(cookieService.removeCookie());
            }

            return new ResponseEntity<>(accountResponse.getAccountResponseDTO(), accountResponse.getHttpStatus());
        }
        catch (NumberFormatException e) {
            return new ResponseEntity<>(null, HttpStatus.BAD_REQUEST);
        }
    }

}
